package com.fmatos.service.album.downloader.rss;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;

import com.fmatos.service.album.domain.Album;
import com.fmatos.service.album.domain.Photo;
import com.fmatos.service.album.downloader.EmptyAlbum;
import com.fmatos.service.album.downloader.ImageDownloader;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;

/**
 * @author fdematos
 *
 */

abstract public class AbstractRssDownloader implements ImageDownloader {

	private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRssDownloader.class);
	public static final int MAX_PHOTOS = 20;

	abstract public String getFeedUrl() ;

	public String getImageTagRegex() {
//		return  ".*[<](/)?img[^>]*src=[\"\']([^>]*)[\"\'][^>]*[>].*"; // Very good regex
//		return  "(.*)[<](/)?img[^>]*src=[\"\']([^\"]*)[\"\'][^>]*[>](.*)"; // better yet regex
		
//		return  "(.*)[<](/)?img[^>]*src=[\"\']([^\"^\']*)[\"\'][^>]*[>](.*)"; // better yet yet regex ---> test this with JPL
		return  "(.*)[<](/)?img[^>]*src=[\"\']([^\"^\']*)([\"\'][^>]*[>].*)"; // better yet yet yet regex --> test with botanical gardens
	}

	public String getRandomPhotoUrl() {

		Album album = getRandomAlbum();
		if ( album.getPhotos() != null && album.getPhotos().size() > 0) {
			return album.getPhotos().get(0).getUrl();
		} else {
			return null;
		}
	}

	public Album getRandomAlbum() {
		return doAll();
	}

	private Album doAll() {

		try {
			String url = getFeedUrl();

			SyndFeed feed = buildSyndFeed(url );
			LOGGER.info("Got feed from " + url);

			if ( feed == null ) {
				return new EmptyAlbum();
			}
			return processFeed(feed);

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// Allows this method to be mocked
	protected InputStream getInputStream(String url) {
		URLConnection openConnection;

		try {
			openConnection = new URL(url).openConnection();
			InputStream is = openConnection.getInputStream();

			if("gzip".equals(openConnection.getContentEncoding())){
				is = new GZIPInputStream(is);
			}   

			return is;
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
		
	}
	
	private SyndFeed buildSyndFeed(String url) {
	
			InputStream is = getInputStream(url);
		
			InputSource source = new InputSource(is);
			
//			source.setEncoding("ISO-8859-1");
			
			SyndFeed feed = null;
			SyndFeedInput input = new SyndFeedInput();
			
			try {
				feed = input.build(source);
			} catch (IllegalArgumentException | FeedException e) {
				e.printStackTrace();
			} 
			return feed;

//		} catch (IOException e) {
//			LOGGER.error("Timeout downloading RSS ");


	}

	public Album processFeed(SyndFeed syndFeed) {

		if ( syndFeed == null ) {
			LOGGER.error("No feed to process");
			return null;
		}
		LOGGER.info("Links " + syndFeed.getLink());

		List<Photo> photos = new LinkedList<Photo>();
		Album album = new Album(AbstractRssDownloader.getAlbumName(getFeedUrl()));
		album.setLink(syndFeed.getLink());
		album.setAlternativeLink(getFeedUrl());
		album.setPhotos(photos);


		List<? extends SyndEntryImpl> list = syndFeed.getEntries();

		for(SyndEntryImpl entry: list){
			processEntry(entry,photos);
			if ( photos.size() > MAX_PHOTOS ) {
				photos = photos.subList(0, MAX_PHOTOS);
				album.setPhotos(photos);
				break;
			}
		}

		return album;

	}

	public static String getAlbumName(String url) {
		return "CustomRss" + url.hashCode();
	}

	public void processEntry(SyndEntryImpl entry, List<Photo> photoList) {

		String imageRegex = getImageTagRegex(); 
		Pattern imagePattern = Pattern.compile(imageRegex);

		String html = entry.getDescription().getValue();

		Matcher str = imagePattern.matcher(html);

		if ( str.find()) {
			String url = str.group(3);
			LOGGER.debug("found url {} "  , url);

			String urlWebPage = null;

			Photo ph = new Photo(transformUrlToFullSize(url),transformUrlToThumbnail(url),urlWebPage,entry.getTitle().trim());
			ph.setLink(entry.getLink().trim());
			photoList.add(ph); 
		}

	}

	@Override
	public String transformUrlToFullSize(String url) {
		return url;
	}

	@Override
	public String transformUrlToThumbnail(String url) {
		return url;
	}

}
